package top.jiangqiang.crawler.core.mapstruct;

import org.dromara.hutool.core.map.multi.RowKeyTable;
import org.dromara.hutool.core.reflect.ClassUtil;
import org.dromara.hutool.core.reflect.TypeUtil;
import org.jetbrains.annotations.NotNull;
import org.mapstruct.factory.Mappers;
import top.jiangqiang.crawler.core.exception.CrawlerException;

import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;

public class BeanMapper {
    private static final RowKeyTable<Class<?>, Class<?>, Converter<?, ?>> cells = new RowKeyTable<>();

    static {
        Set<Class<?>> classes = ClassUtil.scanPackageBySuper("top.jiangqiang.crawler.core.mapstruct", Converter.class);
        for (Class<?> aClass : classes) {
            if (aClass.isInterface()) {
                Type[] typeArguments = TypeUtil.getTypeArguments(aClass);
                cells.put((Class<?>) typeArguments[0], (Class<?>) typeArguments[1], (Converter<?, ?>) Mappers.getMapper(aClass));
            }
        }
    }

    /**
     * 对象类型转换
     *
     * @param source    源对象
     * @param distClass 目标类型
     * @return 目标类型的对象
     */
    public static <S, D> D convert(@NotNull S source, @NotNull Class<D> distClass) {
        Converter<?, ?> converter = cells.get(source.getClass(), distClass);
        if (converter == null) {
            throw new CrawlerException("转换器不存在");
        }
        @SuppressWarnings("unchecked")
        Converter<S, D> tuConverter = (Converter<S, D>) converter;
        return tuConverter.convert(source);
    }

    /**
     * 转换集合类型
     *
     * @return
     */
    public static <S, D> List<D> convertList(@NotNull Collection<S> sourceCollection, @NotNull Class<D> clazz) {
        return sourceCollection.stream().map(item -> convert(item, clazz)).toList();
    }

    public static <S, D> List<D> convertList(@NotNull S[] sourceArray, @NotNull Class<D> clazz) {
        return Arrays.stream(sourceArray).map(item -> convert(item, clazz)).toList();
    }
}